---@type CS.FairyEditor.App
local app = App

---listToTable
---@param list CS.System.Collections.Generic.List_CS.System.String
---@return string[]
local function listToTable(list)
    local count = list.Count
    local result = {}
    for i = 0, count - 1 do
        result[i + 1] = list[i]
    end
    return result
end

---arrayToTable
---@param list any
---@return string[]
local function arrayToTable(list)
    local count = list.Length
    local result = {}
    for i = 0, count - 1 do
        result[i + 1] = list[i]
    end
    return result
end

---@param item CS.FairyEditor.FPackageItem
---@param ownerPackageName string
---@return boolean
local function IsReferneceByOtherPackage(item, ownerPackageName)
    local query = CS.FairyEditor.DependencyQuery()
    query:QueryReferences(app.project, item:GetURL())
    ---@type CS.FairyEditor.ReferenceInfo[]
    local references = listToTable(query.references)
    for _, info in ipairs(references) do
        if info.ownerPkg.name ~= ownerPackageName then
            return true
        end
    end
    return false
end

---@param package CS.FairyEditor.FPackage
---@return boolean
local function clearPackageExported(package)
    local changed = false
    local packageName = package.name
    ---@type CS.FairyEditor.FPackageItem[]
    local items = listToTable(package.items)
    for _, item in ipairs(items) do
        local exported = IsReferneceByOtherPackage(item, packageName)
        if exported ~= item.exported then
            app.libView:SetResourcesExported({item}, exported)
            fprint(string.format("set resource: ui://%s/%s exported:%s", packageName, item.name, exported and "true" or "false"))
        end
    end
    return changed
end

local function clearAllPackageExported()
    local changed = false
    ---@type CS.FairyEditor.FPackage[]
    local packages = listToTable(app.project.allPackages)
    for _, package in ipairs(packages) do
        if clearPackageExported(package) then
            changed = true
        end
    end
    return changed
end

local function refreshProject()
    app.project:SetChanged()
    app.project:Save()
    app.OpenProject(string.format("%s/%s.fairy", app.project.basePath, app.project.name))
end

---@return CS.FairyEditor.FPackage
local function getSelectedPackage()
    if not app.libView.focused then return end
    ---@type CS.FairyEditor.FPackageItem
    local item = app.libView:GetSelectedFolder()
    if not item then return end
    return item.owner
end

local editMenu = app.menu:GetSubMenu("tool")
editMenu:AddItem("清理所有导出项", "clear_all_export_setting", 0, false, function(menuItem)
    local selected = getSelectedPackage()
    if selected then
        fprint(string.format("selected:: %s", selected.name))
        clearPackageExported(selected)
    else
        app.Confirm("是否清除所有包中的导出项？", function(result)
            if result == "yes" then
                clearAllPackageExported()
            end
        end)
    end
end)

editMenu:AddItem("打印所有导出项", "print_all_exported_items", 1, false, function(menuItem)
    local packages = listToTable(app.project.allPackages)
    for _, package in ipairs(packages) do
        ---@type CS.FairyEditor.FPackageItem[]
        local items = listToTable(package.items)
        for _, item in ipairs(items) do
            if item.exported then
                fprint(string.format("exported >> ui://%s/%s  %s", item.owner.name, item.name, item:GetURL()))
            end
        end
    end
end)

function onDestroy()
    -------do cleanup here-------
    local editMenu = app.menu:GetSubMenu("tool")
    editMenu:RemoveItem("clear_all_export_setting")
    editMenu:RemoveItem("print_all_exported_items")
end
